﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsGame4
{
    class Enemy_MoveState : State
    {
        private static Enemy_MoveState instance;

        private Enemy_MoveState()
        {
            base.Name = "MoveState";
        }

        public override void enter(AIObject aiObject)
        {
            //System.Console.WriteLine("moveenterstate");
        }

        public static Enemy_MoveState getInstance()
        {
            if (instance == null)
                instance = new Enemy_MoveState();
            return instance;
        }

        public override void execute(AIObject aiObject)
        {
            AIEnemy aiEnemy = (AIEnemy)aiObject;
            Enemy enemy = (Enemy)aiEnemy.Enemy;
            GameInfo gameInfo = GameInfo.getInstance();
            //System.Console.WriteLine("movestate");
            // Check if the enemy can attack
            if (enemy.ReloadTime > 0)
                enemy.ReloadTime -= enemy.Level;
            else
                enemy.Attack = true;

            // Move enemy
            int rowEnemy = gameInfo.World.getNumRow(enemy.Position.Y);
            int columnEnemy = gameInfo.World.getNumColumn(enemy.Position.X);
            enemy.PreviousPosition = new Position2D(enemy.Position.X, enemy.Position.Y);

            if (enemy.Movement != null)
            {
                int dx = enemy.Position.X - enemy.Movement.X;
                int dy = enemy.Position.Y - enemy.Movement.Y;
                if (dx == 0 && dy == 0)
                {
                    enemy.Movement = null;
                    enemy.Route.RemoveAt(0);
                }
                else
                {
                    enemy.Position.X -= (enemy.Speed * Math.Sign(dx));
                    enemy.Position.Y -= (enemy.Speed * Math.Sign(dy));
                }
            }
            //System.Console.WriteLine("1");
            // Check colision with item
            gameInfo.checkItem(enemy);
            //System.Console.WriteLine("2");
            // Move
            if (enemy.Movement == null && enemy.Route != null && enemy.Route.Count > 0)
            {
                // Check if the player is in the vision
                Boolean attack = false;
                //System.Console.WriteLine("move");
                Object obj = gameInfo.detectEnemy(enemy);
                if (obj != null && enemy.GunAmmo > 0)
                {
                    // Attack
                    gameInfo.attackGun(enemy);
                }
                else
                {
                    Cell cellRoute = (Cell)enemy.Route[0];
                    Cell cell = gameInfo.World.get(cellRoute.Row, cellRoute.Column);
                    if (cell.Obj == null)
                        enemy.Movement = new Position2D(cellRoute.Column * gameInfo.World.Size, cellRoute.Row * gameInfo.World.Size);
                    else
                    {
                        EventEmitter.getInstance().registerMessage(0, aiEnemy.Id, aiEnemy.Id, Message.MessageType.msg_stop);
                    }


                    // Check next direction
                    if (enemy.Route.Count >= 2)
                    {
                        Cell nextCell = (Cell)enemy.Route[1];
                        int dx = nextCell.Column - cellRoute.Column;
                        int dy = nextCell.Row - cellRoute.Row;
                        enemy.Direction = new Direction2D(dx, dy);
                    }
                }
            }
            else
            {
                //System.Console.WriteLine("3");
                if (enemy.Movement == null || enemy.Route == null || enemy.Route.Count == 0)
                    EventEmitter.getInstance().registerMessage(0, aiEnemy.Id, aiEnemy.Id, Message.MessageType.msg_stop);
            }

            //System.Console.WriteLine("exitmovestate");
            /*
            // Update world
            //player.PreviousPosition = new Position2D(player.Position.X, player.Position.Y);
            rowEnemy = gameInfo.World.getNumRow(enemy.Position.Y);
            columnEnemy = gameInfo.World.getNumColumn(enemy.Position.X);
            int previousRow = gameInfo.World.getNumRow(enemy.PreviousPosition.Y);
            int previousColumn = gameInfo.World.getNumColumn(enemy.PreviousPosition.X);
            if (rowEnemy != previousRow || columnEnemy != previousColumn)
            {
                Cell cell = gameInfo.World.get(previousRow, previousColumn);
                cell.Obj = null;
                cell = gameInfo.World.get(rowEnemy, columnEnemy);
                cell.Obj = enemy;
            }
            */
        }
     

        public override void exit(AIObject aiObject)
        {
            //Console.WriteLine("<Enemy_StopState> exit");
            AIEnemy aiEnemy = (AIEnemy)aiObject;
        }

        public override Boolean onMessage(AIObject aiObject, Message message)
        {
            //Console.WriteLine("<Enemy_MoveState> onMessage " + message.Type);
            Boolean correct = false;
            switch (message.Type)
            {
                case Message.MessageType.msg_stop:
                    {
                        aiObject.StateMachine.changeState(Enemy_StopState.getInstance());
                        correct = true;
                        break;
                    }
                case Message.MessageType.msg_newShoot:
                    {
                        AIEnemy aiEnemy = (AIEnemy)aiObject;
                        aiEnemy.Enemy.Attack = true;
                        correct = true;
                        break;
                    }
                case Message.MessageType.msg_attacked:
                    {
                        AIEnemy aiEnemy = (AIEnemy)aiObject;
                        aiObject.StateMachine.changeState(Enemy_DestroyState.getInstance());
                        correct = true;
                        break;
                    }
                case Message.MessageType.msg_disableBlinking:
                    {
                        AIEnemy aiEnemy = (AIEnemy)aiObject;
                        Enemy enemy = (Enemy)aiEnemy.Enemy;
                        enemy.Blinking = false;
                        correct = true;
                        break;
                    }
            }
            return correct;
        }
    }
}
